package com.cmic.rcs.emoji.service.impl;

import com.cmic.rcs.emoji.common.UserContext;
import com.cmic.rcs.emoji.entity.pojo.TBusinessTopology;
import com.cmic.rcs.emoji.mapper.TBusinessTopologyMapper;
import com.cmic.rcs.emoji.service.BusinessTopologyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 业务拓扑图服务实现类
 * 
 * @author 系统生成
 * @since 2025-10-15
 */
@Service
@Slf4j
public class BusinessTopologyServiceImpl implements BusinessTopologyService {

    @Autowired
    private TBusinessTopologyMapper businessTopologyMapper;

    // 支持的图片格式
    private static final List<String> SUPPORTED_IMAGE_FORMATS = Arrays.asList("jpg", "jpeg", "png", "gif");
    // 最大文件大小限制 (50MB)
    private static final long MAX_FILE_SIZE = 50 * 1024 * 1024;
    // 图片存储路径
    @Value("${image.host}")
    private  String IMAGE_STORAGE_PATH;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TBusinessTopology uploadTopology(MultipartFile file, String enterpriseCode) {
        // 1. 校验参数
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }
        if (StringUtils.isBlank(enterpriseCode)) {
            throw new RuntimeException("企业编码不能为空");
        }

        // 2. 校验文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new RuntimeException("文件大小不能超过50MB");
        }

        // 3. 校验文件格式
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            throw new RuntimeException("文件名不能为空");
        }
        String fileExtension = getFileExtension(originalFilename).toLowerCase();
        if (!SUPPORTED_IMAGE_FORMATS.contains(fileExtension)) {
            throw new RuntimeException("仅支持JPG/JPEG/PNG/GIF格式的图片");
        }

        // 4. 检查并创建存储目录
        File directory = new File(IMAGE_STORAGE_PATH);
        if (!directory.exists() && !directory.mkdirs()) {
            throw new RuntimeException("无法创建图片存储目录");
        }

        // 5. 生成唯一文件名
        String newFilename = UUID.randomUUID().toString() + "." + fileExtension;
        // 修改 uploadTopology 方法中的文件保存逻辑
        String filePath = IMAGE_STORAGE_PATH + File.separator + newFilename;

// 确保路径以斜杠结尾
        if (!IMAGE_STORAGE_PATH.endsWith(File.separator)) {
            filePath = IMAGE_STORAGE_PATH + File.separator + newFilename;
        }

        try {
            // 6. 保存文件到本地
            Path path = Paths.get(filePath);

            // 创建父目录（如果不存在）
            Path parentDir = path.getParent();
            if (parentDir != null && !Files.exists(parentDir)) {
                Files.createDirectories(parentDir);
            }

            // 使用更安全的文件写入方式
            Files.write(path, file.getBytes());
            log.info("图片上传成功，文件路径：{}", filePath);

            // 7. 检查是否已存在该企业的拓扑图，如果存在则删除
            TBusinessTopology existingTopology = businessTopologyMapper.selectByEnterpriseCode(enterpriseCode);
            if (existingTopology != null) {
                // 删除旧文件
                File oldFile = new File(existingTopology.getImageUrl());
                if (oldFile.exists() && !oldFile.delete()) {
                    log.warn("无法删除旧图片文件：{}", existingTopology.getImageUrl());
                }
                // 删除数据库记录
                businessTopologyMapper.deleteByID(existingTopology.getId());
            }

            // 8. 保存到数据库
            TBusinessTopology topology = new TBusinessTopology();
            topology.setEnterpriseCode(enterpriseCode);
            topology.setImageName(originalFilename);
            topology.setImageUrl(filePath);
            topology.setImageSize(file.getSize());
            topology.setUploadBy(UserContext.getUserDto().getUsername());
            topology.setUploadTime(LocalDateTime.now());
            topology.setUpdateTime(LocalDateTime.now());
            topology.setImageType(fileExtension.equals("gif") ? "GIF" : "STATIC");
            topology.setDisplayOrder(1);

            businessTopologyMapper.insert(topology);
            log.info("拓扑图信息保存成功，企业编码：{}", enterpriseCode);

            return topology;

        } catch (IOException e) {
            log.error("图片上传失败：{}", e.getMessage());
            throw new RuntimeException("图片上传失败，请稍后重试");
        }
    }

    @Override
    public TBusinessTopology getTopologyByEnterpriseCode(String enterpriseCode) {
        if (StringUtils.isBlank(enterpriseCode)) {
            throw new RuntimeException("企业编码不能为空");
        }
        return businessTopologyMapper.selectByEnterpriseCode(enterpriseCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTopologyByEnterpriseCode(String enterpriseCode) {
        if (StringUtils.isBlank(enterpriseCode)) {
            throw new RuntimeException("企业编码不能为空");
        }

        // 1. 查询拓扑图信息
        TBusinessTopology topology = businessTopologyMapper.selectByEnterpriseCode(enterpriseCode);
        if (topology == null) {
            log.warn("未找到该企业的拓扑图，企业编码：{}", enterpriseCode);
            return;
        }

        // 2. 删除本地文件
        File file = new File(topology.getImageUrl());
        if (file.exists() && !file.delete()) {
            log.warn("无法删除图片文件：{}", topology.getImageUrl());
        }

        // 3. 删除数据库记录
        businessTopologyMapper.deleteByEnterpriseCode(enterpriseCode);
        log.info("拓扑图删除成功，企业编码：{}", enterpriseCode);
    }

    /**
     * 获取文件扩展名
     * @param filename 文件名
     * @return 文件扩展名
     */
    private String getFileExtension(String filename) {
        int lastDotIndex = filename.lastIndexOf(".");
        if (lastDotIndex > 0) {
            return filename.substring(lastDotIndex + 1);
        }
        return "";
    }
}